/*****************************************************************************
*
*  @file     PmuDriver.c
*  @brief    低功耗驱动
*
*  @author   潘学林
*  @email                                        
*  @version  V0.000
*  @date     2022/9/19
*  @license  /
*----------------------------------------------------------------------------*
*  Remark         : Description                                              *
*----------------------------------------------------------------------------*
*  Change History :                                                          *
*  <Date>     | <Version> | <Author>       | <Description>                   *
*----------------------------------------------------------------------------*
*  2022/9/19  | 0.000     | 潘学林         | 创建文件                        *
*----------------------------------------------------------------------------*
*
*****************************************************************************/

/* Includes ------------------------------------------------------------------*/

#include "PmuDriver.h"  


/* Micros/Enumerate/Structures -----------------------------------------------*/

/* Variables -----------------------------------------------------------------*/

/* Functions -----------------------------------------------------------------*/

/*****************************************
* 内部函数
*****************************************/

/*	1. 关中断
	2. 关掉systick及其他所有唤醒源，初始化2s定时器并开启中断【只保留此唤醒方式】，将未使用的引脚配置为模拟输入，关闭时钟？
	3. 开中断
	4. 进入休眠
	5. 进入定时器中断后是否需要启动系统时钟？
	6. 关中断
	7. 开中断
 */

/**
  * @brief  RTC闹钟初始化
  * @param  None
  * @retval None
  */
void PmuDriver_RtcAlarmInit(void)
{
    /* enable BKPI clock */
    rcu_periph_clock_enable(RCU_BKPI);
    /* allow access to backup domain */
    pmu_backup_write_enable();
    /* reset backup domain */
    bkp_deinit();
    
    /* enable IRC40K */
    rcu_osci_on(RCU_IRC40K);
    /* wait till IRC40K is ready */
    rcu_osci_stab_wait(RCU_IRC40K);
    /* select RCU_IRC40K as RTC clock source */
    rcu_rtc_clock_config(RCU_RTCSRC_IRC40K);
    /* enable RTC clock */
    rcu_periph_clock_enable(RCU_RTC);

    /* wait for RTC registers synchronization */
    rtc_register_sync_wait();
    /* wait until last write operation on RTC registers has finished */
    rtc_lwoff_wait();
    /* enable the RTC alarm interrupt */
    rtc_interrupt_enable(RTC_INT_ALARM);
    /* wait until last write operation on RTC registers has finished */
    rtc_lwoff_wait();
    /* set RTC prescaler: set RTC period to 1s */
    rtc_prescaler_set(40000);
    /* wait until last write operation on RTC registers has finished */
    rtc_lwoff_wait();
    rtc_counter_set(0U);
    /* wait until last write operation on RTC registers has finished */
    rtc_lwoff_wait();
    rtc_alarm_config(PMU_ALARM_TIME_INTERVAL);   
    /* wait until last write operation on RTC registers has finished */
    rtc_lwoff_wait();
    /* clear the RTC alarm flag */
    rtc_flag_clear(RTC_FLAG_ALARM);
}

/**
  * @brief  FWDG初始化【定时精度不高】
  * @param  None
  * @retval None
  */
void PmuDriver_FwdgInit(void)
{
	/* enable IRC40K */
    rcu_osci_on(RCU_IRC40K);
    
    /* wait till IRC40K is ready */
    while(SUCCESS != rcu_osci_stab_wait(RCU_IRC40K))
	{
		
    }
	
	/* confiure FWDGT counter clock: 40KHz(IRC40K) / 64 = 0.625 KHz */
    fwdgt_config(1250,FWDGT_PSC_DIV64);
    
    /* After 2 seconds to generate a reset */
    fwdgt_enable();
}

/*****************************************
* 接口函数
*****************************************/

/**
  * @brief  进入低功耗模式
  * @param  None
  * @retval None
  */
void PmuDriver_EnterStandByMode(void)
{	
	/* enable PMU clock */
    rcu_periph_clock_enable(RCU_PMU);
    /* configure RTC */
    PmuDriver_RtcAlarmInit();
	
	/* init fwdg */
	/* PmuDriver_FwdgInit(); */
	
    /* PMU enters standby mode */
    pmu_to_standbymode(WFI_CMD);
	
	while(1)
	{
		delay_1ms(1000);
	}
}

/********************************* END OF FILE ********************************/
